from collections import OrderedDict
from .html import xhtml_escape

class TagBuilder:
    def __init__(self, tag, attrs=None, inner_html=''):
        self.tag = tag
        self.attributes = OrderedDict(attrs) if attrs else OrderedDict()
        self.inner_html = inner_html

    def add_class(self, value):
        if value:
            cur_value = self.attributes.get('class')
            self.attributes['class'] = cur_value + " " + value if cur_value else value

    def add_attr(self, key, value):
        if not key:
            raise ValueError('key can not be empty.')

        if value is not None:
            if not key in self.attributes:
                self.attributes[key] = value

    def set_attr(self, key, value):
        if not key:
            raise ValueError('key can not be empty.')

        if value is not None:
            self.attributes[key] = value

    def set_inner_html(self, value):
        self.inner_html = value if value is not None else ''

    def _get_attr_str(self, escape):
        result = []
        for k, v in self.attributes.items():
            if escape:
                v = xhtml_escape(v)
            result.extend((' ', k, '="', v, '"'))
        return ''.join(result)

    def generate(self, mode=None, escape_attr=True):
        if not mode:
            return '<{0}{1}>{2}</{0}>'.format(self.tag, self._get_attr_str(escape_attr), self.inner_html)
        elif mode == 'self_closing':
            assert not self.inner_html, 'self closing html element has inner html.'
            return '<' + self.tag + self._get_attr_str(escape_attr) + ' />'
        elif mode == 'start':
            return '<' + self.tag + self._get_attr_str(escape_attr) + '>'
        elif mode == 'end':
            return '</' + self.tag + '>'
        else:
            raise ValueError('unexpected mode: ' + str(mode))

